package com.hx.jeeadminbase.db.utils;

import cn.hutool.json.JSONUtil;
import com.hx.jeeadminbase.utils.StringUtil;
import org.springframework.util.LinkedCaseInsensitiveMap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.Set;

/**
 * @Author: xinmiao.xu
 * @Emial: louis_hsu@yeah.net
 * @CreateDate: 2015年4月21日 下午4:14:42
 * @Description: SQL 通用结果集类型
 */
public class Record extends LinkedCaseInsensitiveMap<Object> implements java.io.Serializable {

	private static final long serialVersionUID = -8705602531566009925L;

	public Record() {
	}

	@SuppressWarnings("unchecked")
	public <T> T getValue(String column) {
		return (T) this.get(column);
	}

	@SuppressWarnings("unchecked")
	public <T> T getValue(String column, Object defaultValue) {
		Object result = this.getValue(column);
		return (T) (result != null ? result : defaultValue);
	}

	private String getStr(String column) {
		return this.getValue(column) != null ? this.getValue(column).toString() : null;
	}

	public String getString(String column) {
		return getStr(column);
	}

	public Integer getInt(String column) {
		Integer v = null;
		try {
			v = getNumber(column).intValue();
		} catch (Exception e) {
			try {
				v = Integer.parseInt(getStr(column));
			} catch (Exception ex) {
				v = null;
			}
		}
		return v;
	}

	public Long getLong(String column) {
		Long v = null;
		try {
			v = getNumber(column).longValue();
		} catch (Exception e) {
			try {
				v = Long.parseLong(getStr(column));
			} catch (Exception ex) {
				v = null;
			}
		}
		return v;
	}

	public Short getShort(String column) {
		Short v = null;
		try {
			v = getNumber(column).shortValue();
		} catch (Exception e) {
			try {
				v = Short.parseShort(getStr(column));
			} catch (Exception ex) {
				v = null;
			}
		}
		return v;
	}

	public Byte getByte(String column) {
		Byte v = null;
		try {
			v = getNumber(column).byteValue();
		} catch (Exception e) {
			try {
				v = Byte.parseByte(getStr(column));
			} catch (Exception ex) {
				v = null;
			}
		}
		return v;
	}

	public java.math.BigInteger getBigInteger(String column) {
		return (java.math.BigInteger) this.getValue(column);
	}

	public java.util.Date getDate(String column) {
		return (java.util.Date) this.getValue(column);
	}

	public java.sql.Time getTime(String column) {
		return (java.sql.Time) this.getValue(column);
	}

	public java.sql.Timestamp getTimestamp(String column) {
		return (java.sql.Timestamp) this.getValue(column);
	}

	public Double getDouble(String column) {
		Double v = null;
		try {
			v = getNumber(column).doubleValue();
		} catch (Exception e) {
			try {
				v = Double.parseDouble(getStr(column));
			} catch (Exception ex) {
				v = null;
			}
		}
		return v;
	}

	public Float getFloat(String column) {
		Float v = null;
		try {
			v = getNumber(column).floatValue();
		} catch (Exception e) {
			try {
				v = Float.parseFloat(getStr(column));
			} catch (Exception ex) {
				v = null;
			}
		}
		return v;
	}

	public Boolean getBoolean(String column) {
		try {
			String v = getStr(column);
			if (v != null && (v.trim().toLowerCase().equals("1") || v.trim().toLowerCase().equals("true"))) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return null;
		}
	}

	public java.math.BigDecimal getBigDecimal(String column) {
		return new BigDecimal(getStr(column));
	}

//	public byte[] getBytes(String column) {
//		Object obj = this.get(column);
//		if(obj!=null && obj.getClass().equals(com.mysql.cj.jdbc.Blob.class)){
//			com.mysql.cj.jdbc.Blob blob = (com.mysql.cj.jdbc.Blob)obj;
//			InputStream inStream=null;
//			byte[] data;
//			long nLen=0;
//	        try {
//				try {
//					inStream = blob.getBinaryStream();
//					nLen = blob.length();
//					int nSize = (int) nLen;
//		            data = new byte[nSize];
//		            inStream.read(data);//将输入流中的数据读到数组中
//		            return data;
//				} catch (Exception e) {
//					e.printStackTrace();
//				} finally{
//					if(inStream!=null){
//						try{
//							inStream.close();
//						}catch(Exception e1){}
//					}
//				}
//	        }catch(Exception ex){
//	        	ex.printStackTrace();
//	        }
//		}
//		return (byte[]) this.getValue(column);
//	}

	public Number getNumber(String column) {
		return (Number) this.getValue(column);
	}
	
//	public String getClobString(String column) {
//		Object obj = this.get(column);
//		if (obj instanceof com.alibaba.druid.proxy.jdbc.ClobProxyImpl) {
//			java.sql.Clob clob = null;
//			com.alibaba.druid.proxy.jdbc.ClobProxyImpl impl = (com.alibaba.druid.proxy.jdbc.ClobProxyImpl) obj;
//			clob = impl.getRawClob(); // 获取原生的这个 Clob
//			try {
//				return ClobToString(clob);
//			} catch (SQLException e) {
//				e.printStackTrace();
//				return null;
//			} catch (IOException e) {
//				e.printStackTrace();
//				return null;
//			}
//		} else {
//			/*CLOB clob = (oracle.sql.CLOB) obj;
//			try {
//				return ClobToString(clob);
//			} catch (SQLException e) {
//				e.printStackTrace();
//				return null;
//			} catch (IOException e) {
//				e.printStackTrace();
//				return null;
//			}*/
//			return null;
//		}
//	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(super.toString()).append(" {");
		boolean first = true;
		for (Entry<String, Object> e : this.entrySet()) {
			if (first)
				first = false;
			else
				sb.append(", ");

			Object value = e.getValue();
			if (value != null)
				value = value.toString();
			sb.append(e.getKey()).append(":").append(value);
		}
		sb.append("}");
		return sb.toString();
	}

	public boolean equals(Object o) {
		if (!(o instanceof Record))
			return false;
		if (o == this)
			return true;
		return this.equals(((Record) o));
	}

	public int hashCode() {
		return this == null ? 0 : this.hashCode();
	}

	public String[] getColumnNames() {
		Set<String> attrNameSet = this.keySet();
		return attrNameSet.toArray(new String[attrNameSet.size()]);
	}

	public Object[] getColumnValues() {
		java.util.Collection<Object> attrValueCollection = this.values();
		return attrValueCollection.toArray(new Object[attrValueCollection.size()]);
	}

	public String toJson() {
		return JSONUtil.toJsonStr(this);
	}
	
	public static String ClobToString(Clob clob) throws SQLException, IOException {
		String reString = "";
		Reader is = clob.getCharacterStream();// 得到流
		BufferedReader br = new BufferedReader(is);
		String s = br.readLine();
		StringBuffer sb = new StringBuffer();
		while (s != null) {// 执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING
			sb.append(s);
			s = br.readLine();
		}
		reString = sb.toString();
		return reString;
	}
	
//	public static String BLOBToString(com.mysql.cj.jdbc.Blob BlobContent) {
//		InputStream ins = null;
//		try {
//			ins = BlobContent.getBinaryStream();
//			return StringUtil.inputStream2StringNoCharset(ins);
//		} catch (SQLException e) {
//			e.printStackTrace();
//			return null;
//		} finally{
//			if(ins!=null){
//				try {
//					ins.close();
//				} catch (Exception e2) {
//				}
//			}
//		}
//	}
	
	public static String BLOBToString(java.sql.Blob BlobContent){
		InputStream ins = null;
		try {
			ins = BlobContent.getBinaryStream();
			return StringUtil.inputStream2StringNoCharset(ins);
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		} finally{
			if(ins!=null){
				try {
					ins.close();
				} catch (Exception e2) {
				}
			}
		}
	}
}
